import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:photo_pipeline/photo_pipeline.dart';

import '../constants/colors.dart';
import '../constants/text_styles.dart';
import '../constants/spacing.dart';
import '../providers/pipeline_providers.dart';
import '../widgets/upload_task_thumbnail.dart';

class UploadTasksScreen extends ConsumerStatefulWidget {
  const UploadTasksScreen({super.key});

  @override
  ConsumerState<UploadTasksScreen> createState() => _UploadTasksScreenState();
}

class _UploadTasksScreenState extends ConsumerState<UploadTasksScreen> {
  final ScrollController _scrollController = ScrollController();
  PageData<UploadTaskAggregate>? _latestPage;
  bool _isLoadingMore = false;
  int _lastEmittedLength = 0;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_onScroll);
  }

  @override
  void dispose() {
    _scrollController.removeListener(_onScroll);
    _scrollController.dispose();
    super.dispose();
  }

  void _onScroll() {
    if (!_scrollController.hasClients) return;
    final position = _scrollController.position;
    if (position.pixels >= position.maxScrollExtent - 240) {
      final page = _latestPage;
      if (page == null) return;
      final hasMore = page.data.length < page.total;
      if (hasMore && !_isLoadingMore) {
        _isLoadingMore = true;
        loadMoreUploadTasks(ref);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final pageAsync = ref.watch(uploadTaskPageProvider);

    return Scaffold(
      appBar: AppBar(
        title: const Text('上传任务'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: () => refreshUploadTasks(ref),
            tooltip: '刷新',
          ),
        ],
      ),
      body: Column(
        children: [
          _buildFilterBar(),
          Expanded(
            child: pageAsync.when(
              data: (page) {
                _latestPage = page;
                if (page.data.length != _lastEmittedLength) {
                  _lastEmittedLength = page.data.length;
                  _isLoadingMore = false;
                }

                if (page.data.isEmpty) {
                  return _buildEmptyState();
                }

                return _buildTaskList(page);
              },
              loading: () => const Center(child: CircularProgressIndicator()),
              error: (error, _) => _buildErrorState(error),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildFilterBar() {
    final status = ref.watch(uploadTaskStatusFilterProvider);

    return Padding(
      padding: const EdgeInsets.fromLTRB(
        AppSpacing.pagePadding,
        AppSpacing.sm,
        AppSpacing.pagePadding,
        AppSpacing.sm,
      ),
      child: Row(
        children: [
          const Text('任务状态', style: AppTextStyles.body2),
          const SizedBox(width: AppSpacing.sm),
          Expanded(
            child: DecoratedBox(
              decoration: BoxDecoration(
                color: const Color(0x0DFFFFFF),
                borderRadius: BorderRadius.circular(12),
                border: Border.all(color: AppColors.divider),
              ),
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 12),
                child: DropdownButton<UploadTaskStatus?>(
                  value: status,
                  isExpanded: true,
                  underline: const SizedBox.shrink(),
                  dropdownColor: AppColors.cardBackground,
                  style: AppTextStyles.body2
                      .copyWith(color: AppColors.textPrimary),
                  items: [
                    const DropdownMenuItem<UploadTaskStatus?>(
                      value: null,
                      child: Text('全部状态'),
                    ),
                    ...UploadTaskStatus.values.map(
                      (s) => DropdownMenuItem<UploadTaskStatus?>(
                        value: s,
                        child: Text(_statusLabel(s)),
                      ),
                    ),
                  ],
                  onChanged: (value) {
                    ref.read(uploadTaskStatusFilterProvider.notifier).state =
                        value;
                    _isLoadingMore = false;
                    _lastEmittedLength = 0;
                    _scrollController.jumpTo(0);
                  },
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildTaskList(PageData<UploadTaskAggregate> page) {
    final hasMore = page.data.length < page.total;
    final itemCount = page.data.length + (hasMore ? 1 : 0);

    return ListView.separated(
      controller: _scrollController,
      padding: const EdgeInsets.only(
        left: AppSpacing.pagePadding,
        right: AppSpacing.pagePadding,
        top: AppSpacing.sm,
        bottom: AppSpacing.pagePadding,
      ),
      itemCount: itemCount,
      separatorBuilder: (_, __) => const SizedBox(height: AppSpacing.sm),
      itemBuilder: (context, index) {
        if (index >= page.data.length) {
          return _buildLoadMoreIndicator();
        }
        final aggregate = page.data[index];
        return _buildTaskItem(aggregate);
      },
    );
  }

  Widget _buildTaskItem(UploadTaskAggregate aggregate) {
    final fileName = aggregate.fileName ??
        '图片 ${aggregate.task.imageSourceId ?? aggregate.task.id ?? '-'}';
    final statusLabel = aggregate.displayStatus;
    final updatedAt = _formatTimestamp(aggregate.task.updatedAt);

    return Container(
      decoration: BoxDecoration(
        color: const Color(0x0AFFFFFF),
        borderRadius: BorderRadius.circular(16),
      ),
      padding: const EdgeInsets.all(AppSpacing.md),
      child: Row(
        children: [
          _buildThumbnail(aggregate),
          const SizedBox(width: AppSpacing.md),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  fileName,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: AppTextStyles.body1
                      .copyWith(color: AppColors.textPrimary),
                ),
                const SizedBox(height: 6),
                Text(
                  statusLabel,
                  style: AppTextStyles.body2
                      .copyWith(color: AppColors.textSecondary),
                ),
                if (aggregate.statusMessage != null &&
                    aggregate.statusMessage!.isNotEmpty)
                  Padding(
                    padding: const EdgeInsets.only(top: 4),
                    child: Text(
                      aggregate.statusMessage!,
                      maxLines: 2,
                      overflow: TextOverflow.ellipsis,
                      style: AppTextStyles.caption
                          .copyWith(color: AppColors.textSecondary),
                    ),
                  ),
                if (aggregate.shouldShowProgress) ...[
                  const SizedBox(height: 8),
                  ClipRRect(
                    borderRadius: BorderRadius.circular(8),
                    child: LinearProgressIndicator(
                      value: aggregate.progressPercent / 100,
                      minHeight: 6,
                      backgroundColor: AppColors.divider,
                      valueColor: const AlwaysStoppedAnimation<Color>(
                        AppColors.primary,
                      ),
                    ),
                  ),
                ],
              ],
            ),
          ),
          const SizedBox(width: AppSpacing.sm),
          Column(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              Container(
                padding: const EdgeInsets.symmetric(
                  horizontal: 10,
                  vertical: 4,
                ),
                decoration: BoxDecoration(
                  color: _statusColor(aggregate.task.status).withOpacity(0.15),
                  borderRadius: BorderRadius.circular(12),
                ),
                child: Text(
                  _statusLabel(aggregate.task.status),
                  style: AppTextStyles.caption.copyWith(
                    color: _statusColor(aggregate.task.status),
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ),
              const SizedBox(height: 8),
              Text(
                updatedAt,
                style: AppTextStyles.caption
                    .copyWith(color: AppColors.textSecondary),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildThumbnail(UploadTaskAggregate aggregate) {
    return UploadTaskThumbnail(
      fileInfo: aggregate.fileInfo,
      size: 56,
    );
  }

  Widget _buildLoadMoreIndicator() {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: AppSpacing.sm),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: const [
          SizedBox(
            width: 20,
            height: 20,
            child: CircularProgressIndicator(strokeWidth: 2),
          ),
          SizedBox(width: AppSpacing.sm),
          Text('加载更多中...', style: AppTextStyles.caption),
        ],
      ),
    );
  }

  Widget _buildEmptyState() {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(AppSpacing.lg),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const [
            Icon(Icons.cloud_upload_outlined,
                size: 48, color: AppColors.textSecondary),
            SizedBox(height: AppSpacing.sm),
            Text('暂无上传任务', style: AppTextStyles.body1),
            SizedBox(height: AppSpacing.xs),
            Text(
              '开始上传后，这里会显示任务进度。',
              style: AppTextStyles.caption,
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildErrorState(Object error) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(AppSpacing.lg),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Icon(Icons.error_outline, size: 48, color: Colors.redAccent),
            const SizedBox(height: AppSpacing.sm),
            const Text('加载失败', style: AppTextStyles.body1),
            const SizedBox(height: AppSpacing.xs),
            Text(
              '$error',
              textAlign: TextAlign.center,
              style: AppTextStyles.caption
                  .copyWith(color: AppColors.textSecondary),
            ),
            const SizedBox(height: AppSpacing.sm),
            ElevatedButton.icon(
              onPressed: () => refreshUploadTasks(ref),
              icon: const Icon(Icons.refresh),
              label: const Text('重试'),
            ),
          ],
        ),
      ),
    );
  }

  Color _statusColor(UploadTaskStatus status) {
    switch (status) {
      case UploadTaskStatus.pending:
        return Colors.orangeAccent;
      case UploadTaskStatus.uploading:
        return AppColors.primary;
      case UploadTaskStatus.completed:
        return Colors.greenAccent.shade400;
      case UploadTaskStatus.failed:
        return Colors.redAccent;
      case UploadTaskStatus.cancelled:
        return Colors.grey;
      case UploadTaskStatus.paused:
        return Colors.blueGrey;
    }
  }

  String _statusLabel(UploadTaskStatus status) {
    switch (status) {
      case UploadTaskStatus.pending:
        return '待上传';
      case UploadTaskStatus.uploading:
        return '上传中';
      case UploadTaskStatus.completed:
        return '已完成';
      case UploadTaskStatus.failed:
        return '失败';
      case UploadTaskStatus.cancelled:
        return '已取消';
      case UploadTaskStatus.paused:
        return '已暂停';
    }
  }

  String _formatTimestamp(DateTime time) {
    final local = time.toLocal();
    final date = '${local.year}-${local.month.toString().padLeft(2, '0')}-'
        '${local.day.toString().padLeft(2, '0')}';
    final h = local.hour.toString().padLeft(2, '0');
    final m = local.minute.toString().padLeft(2, '0');
    return '$date $h:$m';
  }

}
